package com.zbkj.service.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zbkj.common.constants.Constants;
import com.zbkj.common.constants.IntegralDetailConstants;
import com.zbkj.common.exception.CrmebException;
import com.zbkj.common.model.system.SystemUserLevel;
import com.zbkj.common.model.user.User;
import com.zbkj.common.model.user.UserIntegral;
import com.zbkj.common.model.user.UserIntegralDetail;
import com.zbkj.common.request.UserOperateAllIntegralRequest;
import com.zbkj.common.token.FrontTokenComponent;
import com.zbkj.common.utils.DateUtil;
import com.zbkj.service.dao.UserIntegralDao;
import com.zbkj.service.service.*;
import com.zbkj.service.util.IntegralUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

/**
 * 用户积分记录Service实现类
 * +----------------------------------------------------------------------
 * | CRMEB [ CRMEB赋能开发者，助力企业发展 ]
 * +----------------------------------------------------------------------
 * | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
 * +----------------------------------------------------------------------
 * | Licensed CRMEB并不是自由软件，未经许可不能去掉CRMEB相关版权
 * +----------------------------------------------------------------------
 * | Author: CRMEB Team <admin@crmeb.com>
 * +----------------------------------------------------------------------
 */
@Service
public class UserIntegralServiceImpl extends ServiceImpl<UserIntegralDao, UserIntegral> implements UserIntegralService {

    private static final Logger logger = LoggerFactory.getLogger(UserIntegralServiceImpl.class);

    @Resource
    private UserIntegralDao dao;

    @Autowired
    private UserService userService;
    @Autowired
    private UserIntegralService userIntegralService;

    @Autowired
    private UserIntegralDetailService userIntegralDetailService;

    @Autowired
    private FrontTokenComponent tokenComponet;

    @Autowired
    private IntegralUtil integralUtil;

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Autowired
    private StoreOrderService storeOrderService;

    @Autowired
    private SystemUserLevelService systemUserLevelService;
    /**
     * 定时任务实现（每日营业额下各合伙人每季度的分红）
     * @return User
     */
    @Override
    public void partnerDividendSeason() {
        List<SystemUserLevel> partnerList = systemUserLevelService.getPartnerList();
        List<User> allPartner = userService.getAllPartner();
        List<UserIntegralDetail> details = new ArrayList<>();
        BigDecimal seasonSales = getTotalTurnoverSeason();
        for (User user : allPartner) {
            BigDecimal changeValue = integralUtil.partnerDividendSeason(user.getLevel(), seasonSales, allPartner.size());
            UserIntegral userIntegral = userIntegralService.getById(user.getUid());
            BigDecimal remainder = userIntegral.getBalance().add(changeValue);
            userIntegralService.operationBalance(user.getUid(), changeValue, userIntegral.getBalance(), IntegralDetailConstants.CHANGE_TYPE_ADD);
            String reason = StrUtil.format("增加了{}" + IntegralDetailConstants.INTEGRAL_TYPE_BALANCE + "合伙人季节分红", changeValue);
            UserIntegralDetail balanceDetail = integralUtil.createIntegralDetail(user.getUid(), IntegralDetailConstants.INTEGRAL_TYPE_BALANCE, IntegralDetailConstants.CHANGE_TYPE_ADD, changeValue, reason, remainder);
            details.add(balanceDetail);
        }
    }


        /**
         * 定时任务实现（每日营业额下各合伙人每日的分润）
         * @return User
         */
    @Override
    public void partnerDividendDaily() {
        List<SystemUserLevel> partnerList = systemUserLevelService.getPartnerList();
        List<User> allPartner = userService.getAllPartner();
        List<UserIntegralDetail> details = new ArrayList<>();
        BigDecimal dailySales = getTotalTurnoverDaily();
        for (User user :allPartner) {
            BigDecimal changeValue = integralUtil.partnerDividendDaily(user.getLevel(), dailySales);
            UserIntegral userIntegral = userIntegralService.getById(user.getUid());
            BigDecimal remainder = userIntegral.getBalance().add(changeValue);
            userIntegralService.operationBalance(user.getUid(), changeValue, userIntegral.getBalance(), IntegralDetailConstants.CHANGE_TYPE_ADD);
            String reason = StrUtil.format("增加了{}" + IntegralDetailConstants.INTEGRAL_TYPE_BALANCE + "合伙人每日分润" , changeValue);
            UserIntegralDetail balanceDetail = integralUtil.createIntegralDetail(user.getUid(), IntegralDetailConstants.INTEGRAL_TYPE_BALANCE, IntegralDetailConstants.CHANGE_TYPE_ADD, changeValue, reason, remainder);
            details.add(balanceDetail);
        }
        userIntegralDetailService.saveBatch(details);
    }

    /**
     * 定时任务实现（绿色积分每天释放）
     * @return User
     */
    @Override
    public void greenRelease() {
        List<User> allUser = userService.getAllUser();
        for (User user :allUser) {
            UserIntegral userIntegral = userIntegralService.getById(user.getUid());
            BigDecimal greenChange = integralUtil.releaseOfGreen(userIntegral.getGreenIntegral());
            BigDecimal remainder = userIntegral.getGreenIntegral().subtract(greenChange);
            userIntegralService.operationGreenIntegral(userIntegral.getUid(), greenChange, userIntegral.getGreenIntegral(), IntegralDetailConstants.CHANGE_TYPE_DEC);
            String reason = StrUtil.format("减少了{}" + IntegralDetailConstants.INTEGRAL_TYPE_GREEN + "：每日释放", greenChange);
            UserIntegralDetail greenDetail = integralUtil.createIntegralDetail(userIntegral.getUid(), IntegralDetailConstants.INTEGRAL_TYPE_GREEN, IntegralDetailConstants.CHANGE_TYPE_DEC, greenChange, reason, remainder);
            userIntegralDetailService.save(greenDetail);

        }

    }

    public BigDecimal getTotalTurnoverSeason() { // 获取季节总销售额
        List<User> allUser = userService.getAllUser();
        BigDecimal totalTurnover = BigDecimal.ZERO;
        for (int i = 0; i < allUser.size(); i++) {
            totalTurnover = totalTurnover.add(storeOrderService.getSumPayPriceByUidAndDate(allUser.get(i).getUid(), Constants.SEARCH_DATE_SEASON));
        }
        return totalTurnover;
    }
    public BigDecimal getTotalTurnoverDaily() { // 获取一天总营业额
        List<User> allUser = userService.getAllUser();
        BigDecimal totalTurnover = BigDecimal.ZERO;
        for (int i = 0; i < allUser.size(); i++) {
            totalTurnover = totalTurnover.add(storeOrderService.getSumPayPriceByUidAndDate(allUser.get(i).getUid(), Constants.SEARCH_DATE_DAY));
        }
        return totalTurnover;
    }


    /**
     * 定时任务的实现（增值积分每天0点定时转余额）
     * @return User
     */
    @Override
    public void valueAddTransBalanceDaily() {
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        List<User> allUser = userService.getAllUser();
        List<UserIntegralDetail> details = new ArrayList<>();
        BigDecimal totalTurnover = BigDecimal.ZERO;
        BigDecimal allIntegral = BigDecimal.ZERO;
        for (int i = 0; i < allUser.size(); i++) {
            totalTurnover = totalTurnover.add(storeOrderService.getSumPayPriceByUidAndDate(allUser.get(i).getUid(), Constants.SEARCH_DATE_DAY));
            UserIntegral userIntegral = userIntegralService.getById(allUser.get(i).getUid());
            allIntegral = allIntegral.add(userIntegral.getValueAddIntegral());
        }
        for (int i = 0; i < allUser.size(); i++) {
            UserIntegral userIntegral = userIntegralService.getById(allUser.get(i).getUid());
            BigDecimal subsidyChange = integralUtil.subsidyLogic(totalTurnover, userIntegral.getValueAddIntegral(), allIntegral);
            // 处理余额
            BigDecimal balanceRemainder = userIntegral.getBalance().add(subsidyChange);
            String balanceReason = StrUtil.format("增加了{}" + IntegralDetailConstants.INTEGRAL_TYPE_BALANCE + "：增值积分转余额", subsidyChange);
            UserIntegralDetail balanceDetail = integralUtil.createIntegralDetail(userIntegral.getUid(), IntegralDetailConstants.INTEGRAL_TYPE_BALANCE, IntegralDetailConstants.CHANGE_TYPE_ADD, subsidyChange, balanceReason, balanceRemainder);
            details.add(balanceDetail);
            // 处理增值积分
            BigDecimal valueAddRemainder = userIntegral.getValueAddIntegral().subtract(subsidyChange);
            String valueAddReason = StrUtil.format("减少了{}" + IntegralDetailConstants.INTEGRAL_TYPE_VALUE_ADD + "：增值积分转余额", subsidyChange);
            UserIntegralDetail valueAddDetail = integralUtil.createIntegralDetail(userIntegral.getUid(), IntegralDetailConstants.INTEGRAL_TYPE_VALUE_ADD, IntegralDetailConstants.CHANGE_TYPE_DEC, subsidyChange, valueAddReason, valueAddRemainder);
            details.add(valueAddDetail);
            // 处理贡献值
            BigDecimal ratio = userIntegral.getValueAddIntegral().divide(totalTurnover, 3, RoundingMode.HALF_UP);
            BigDecimal contributionChange = userIntegral.getContributionIntegral().multiply(ratio);
            BigDecimal contributionRemainder = userIntegral.getContributionIntegral().subtract(contributionChange);
            String contributionReason = StrUtil.format("减少了{}" + IntegralDetailConstants.INTEGRAL_TYPE_CONTRIBUTION + "：增值积分减少（同比）", contributionChange);
            UserIntegralDetail contributionDetail = integralUtil.createIntegralDetail(userIntegral.getUid(), IntegralDetailConstants.INTEGRAL_TYPE_CONTRIBUTION, IntegralDetailConstants.CHANGE_TYPE_DEC, subsidyChange, contributionReason, contributionRemainder);
            details.add(contributionDetail);
        }
        userIntegralDetailService.saveBatch(details);
    }


    /**
     * 获取个人资料
     *
     * @return User
     * @author Mr.Zhang
     * @since 2020-04-28
     */
    @Override
    public UserIntegral getInfo() {
        if (getUserId() == 0) {
            return null;
        }
        return getById(getUserId());
    }
    /**
     * 获取当前用户id
     *
     * @return Integer
     * @author Mr.Zhang
     * @since 2020-04-28
     */
    @Override
    public Integer getUserId() {
        Integer id = tokenComponet.getUserId();
        if (null == id) {
            return 0;
        }
        return id;
    }

    public void judgeDataValue(String integralType, Integer changeType, BigDecimal integralValue, BigDecimal nowIntegral) {
        // 减少时要判断小于0的情况,添加时判断是否超过数据限制
        if (changeType.equals(IntegralDetailConstants.CHANGE_TYPE_DEC) && integralValue.compareTo(BigDecimal.ZERO) < 0) {
            if (nowIntegral.subtract(integralValue).compareTo(BigDecimal.ZERO) < 0) {
                throw new CrmebException(integralType + "扣减后不能小于0");
            }
        }
        if (changeType.equals(IntegralDetailConstants.CHANGE_TYPE_ADD) && integralValue.compareTo(BigDecimal.ZERO) < 0) {
            if (nowIntegral.add(integralValue).compareTo(new BigDecimal("99999999.99")) > 0) {
                throw new CrmebException(integralType + "添加后后不能大于99999999.99");
            }
        }
    }

    public void executeOperator (String integralType, Integer uid, BigDecimal integralValue, BigDecimal nowIntegral, Integer changeType) { // 通过传入的积分类型进行对应的操作
        switch (integralType) {
            case IntegralDetailConstants.INTEGRAL_TYPE_VALUE_ADD : operationValueAddIntegral(uid, integralValue, nowIntegral, changeType); break;
            case IntegralDetailConstants.INTEGRAL_TYPE_GREEN: operationGreenIntegral(uid, integralValue, nowIntegral, changeType); break;
            case IntegralDetailConstants.INTEGRAL_TYPE_CONTRIBUTION : operationContributionIntegral(uid, integralValue, nowIntegral, changeType); break;
            case IntegralDetailConstants.INTEGRAL_TYPE_BALANCE : operationBalance(uid, integralValue, nowIntegral, changeType); break;
            case IntegralDetailConstants.INTEGRAL_TYPE_CB_FUNDS : operationCbfunds(uid, integralValue, nowIntegral, changeType); break;
        }
    }

    public Boolean disposeExecute (Integer uid, String integralType, Integer changeType, BigDecimal integralValue, BigDecimal nowIntegral) {
        Boolean execute = transactionTemplate.execute(e -> {
            // 处理余额
            if (integralValue.compareTo(BigDecimal.ZERO) > 0) {
                // 生成userIntegralDetail
                UserIntegralDetail userIntegralDetail = new UserIntegralDetail();
                userIntegralDetail.setUid(uid);
                userIntegralDetail.setIntegralType(integralType);
                userIntegralDetail.setUpdateTime(DateUtil.nowDateTime());

                if (changeType.equals(IntegralDetailConstants.CHANGE_TYPE_ADD)) {// 增加
                    userIntegralDetail.setChangeType(IntegralDetailConstants.CHANGE_TYPE_ADD);
                    userIntegralDetail.setValue(integralValue);
                    userIntegralDetail.setRemainder(nowIntegral.add(integralValue));
                    userIntegralDetail.setReason(StrUtil.format("后台操作增加了{}" + integralType, integralValue));
                    userIntegralDetailService.save(userIntegralDetail);
                    executeOperator(integralType, uid, integralValue, nowIntegral, changeType);
                } else {
                    userIntegralDetail.setChangeType(IntegralDetailConstants.CHANGE_TYPE_DEC);
                    userIntegralDetail.setValue(integralValue);
                    userIntegralDetail.setRemainder(nowIntegral.subtract(integralValue));
                    userIntegralDetail.setReason(StrUtil.format("后台操作扣减了{}" + integralType, integralValue));

                    userIntegralDetailService.save(userIntegralDetail);
                    executeOperator(integralType, uid, integralValue, nowIntegral, changeType);
                }
            }
            return Boolean.TRUE;
        });
        if (!execute) {
            throw new CrmebException("修改失败");
        }
        return execute;
    }


    @Override
    public Boolean updateAllIntegral(UserOperateAllIntegralRequest request) {
        if (ObjectUtil.isNull(request.getValueAddValue()) || ObjectUtil.isNull(request.getGreenValue())
        || ObjectUtil.isNull(request.getContributionValue()) || ObjectUtil.isNull(request.getBalanceValue())
        || ObjectUtil.isNull(request.getCbfundsValue())) {
            throw new CrmebException("至少输入一个金额");
        }
        if (request.getValueAddValue().compareTo(BigDecimal.ZERO) < 0 && request.getGreenValue().compareTo(BigDecimal.ZERO) < 0
        && request.getContributionValue().compareTo(BigDecimal.ZERO) < 0 && request.getBalanceValue().compareTo(BigDecimal.ZERO) < 0
        && request.getCbfundsValue().compareTo(BigDecimal.ZERO) < 0) {
            throw new CrmebException("修改值不能等小于等于0");
        }
        UserIntegral userIntegral= getById(request.getUid());
        if (ObjectUtil.isNull(userIntegral)) {
            throw new CrmebException("用户不存在");
        }

        // 减少时要判断小于0的情况,添加时判断是否超过数据限制
        judgeDataValue(IntegralDetailConstants.INTEGRAL_TYPE_VALUE_ADD, request.getValueAddType(), request.getValueAddValue(), userIntegral.getValueAddIntegral());
        judgeDataValue(IntegralDetailConstants.INTEGRAL_TYPE_GREEN, request.getGreenType(), request.getGreenValue(), userIntegral.getGreenIntegral());
        judgeDataValue(IntegralDetailConstants.INTEGRAL_TYPE_CONTRIBUTION, request.getContributionType(), request.getContributionValue(), userIntegral.getContributionIntegral());
        judgeDataValue(IntegralDetailConstants.INTEGRAL_TYPE_BALANCE, request.getBalanceType(), request.getBalanceValue(), userIntegral.getBalance());
        judgeDataValue(IntegralDetailConstants.INTEGRAL_TYPE_CB_FUNDS, request.getCbfundsType(), request.getCbfundsValue(), userIntegral.getCbfunds());

        Boolean valueAddExecute = disposeExecute(request.getUid(), IntegralDetailConstants.INTEGRAL_TYPE_VALUE_ADD, request.getValueAddType(), request.getValueAddValue(), userIntegral.getValueAddIntegral());
        Boolean greenExecute = disposeExecute(request.getUid(), IntegralDetailConstants.INTEGRAL_TYPE_GREEN, request.getGreenType(), request.getGreenValue(), userIntegral.getGreenIntegral());
        Boolean contributionExecute = disposeExecute(request.getUid(), IntegralDetailConstants.INTEGRAL_TYPE_CONTRIBUTION, request.getContributionType(), request.getContributionValue(), userIntegral.getContributionIntegral());
        Boolean balanceExecute = disposeExecute(request.getUid(), IntegralDetailConstants.INTEGRAL_TYPE_BALANCE, request.getBalanceType(), request.getBalanceValue(), userIntegral.getBalance());
        Boolean cbfundsExecute = disposeExecute(request.getUid(), IntegralDetailConstants.INTEGRAL_TYPE_CB_FUNDS, request.getCbfundsType(), request.getCbfundsValue(), userIntegral.getCbfunds());

        return valueAddExecute && greenExecute && contributionExecute && balanceExecute && cbfundsExecute;

    }

    @Override
    public Boolean updateValueAddIntegral(UserIntegral userIntegral, BigDecimal valueAddIntegral, Integer changeType) {
        LambdaUpdateWrapper<UserIntegral> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
        if (changeType.equals(IntegralDetailConstants.CHANGE_TYPE_ADD)) {
            lambdaUpdateWrapper.set(UserIntegral::getValueAddIntegral, userIntegral.getValueAddIntegral().add(valueAddIntegral));
        } else {
            lambdaUpdateWrapper.set(UserIntegral::getValueAddIntegral, userIntegral.getValueAddIntegral().subtract(valueAddIntegral));
        }
        lambdaUpdateWrapper.eq(UserIntegral::getUid, userIntegral.getUid());
        if (changeType.equals(IntegralDetailConstants.CHANGE_TYPE_DEC)) {
            lambdaUpdateWrapper.apply(StrUtil.format(" value_add_integral - {} >= 0", valueAddIntegral));
        }
        return update(lambdaUpdateWrapper);
    }

    @Override
    public Boolean updateGreenIntegral(UserIntegral userIntegral, BigDecimal greenIntegral, Integer changeType) {
        LambdaUpdateWrapper<UserIntegral> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
        if (changeType.equals(IntegralDetailConstants.CHANGE_TYPE_ADD)) {
            lambdaUpdateWrapper.set(UserIntegral::getGreenIntegral, userIntegral.getGreenIntegral().add(greenIntegral));
        } else {
            lambdaUpdateWrapper.set(UserIntegral::getGreenIntegral, userIntegral.getGreenIntegral().subtract(greenIntegral));
        }
        lambdaUpdateWrapper.eq(UserIntegral::getUid, userIntegral.getUid());
        if (changeType.equals(IntegralDetailConstants.CHANGE_TYPE_DEC)) {
            lambdaUpdateWrapper.apply(StrUtil.format(" green_integral - {} >= 0", greenIntegral));
        }
        return update(lambdaUpdateWrapper);
    }

    @Override
    public Boolean updateContributionIntegral(UserIntegral userIntegral, BigDecimal contributionIntegral, Integer changeType) {
        LambdaUpdateWrapper<UserIntegral> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
        if (changeType.equals(IntegralDetailConstants.CHANGE_TYPE_ADD)) {
            lambdaUpdateWrapper.set(UserIntegral::getContributionIntegral, userIntegral.getContributionIntegral().add(contributionIntegral));
        } else {
            lambdaUpdateWrapper.set(UserIntegral::getContributionIntegral, userIntegral.getContributionIntegral().subtract(contributionIntegral));
        }
        lambdaUpdateWrapper.eq(UserIntegral::getUid, userIntegral.getUid());
        if (changeType.equals(IntegralDetailConstants.CHANGE_TYPE_DEC)) {
            lambdaUpdateWrapper.apply(StrUtil.format(" contribution_integral - {} >= 0", contributionIntegral));
        }
        return update(lambdaUpdateWrapper);
    }

    @Override
    public Boolean updateBalance(UserIntegral userIntegral, BigDecimal balance, Integer changeType) {
        LambdaUpdateWrapper<UserIntegral> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
        if (changeType.equals(IntegralDetailConstants.CHANGE_TYPE_ADD)) {
            lambdaUpdateWrapper.set(UserIntegral::getBalance, userIntegral.getBalance().add(balance));
        } else {
            lambdaUpdateWrapper.set(UserIntegral::getBalance, userIntegral.getBalance().subtract(balance));
        }
        lambdaUpdateWrapper.eq(UserIntegral::getUid, userIntegral.getUid());
        if (changeType.equals(IntegralDetailConstants.CHANGE_TYPE_DEC)) {
            lambdaUpdateWrapper.apply(StrUtil.format(" balance - {} >= 0", balance));
        }
        return update(lambdaUpdateWrapper);
    }

    @Override
    public Boolean updateCbfunds(UserIntegral userIntegral, BigDecimal cbfunds, Integer changeType) {
        LambdaUpdateWrapper<UserIntegral> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
        if (changeType.equals(IntegralDetailConstants.CHANGE_TYPE_ADD)) {
            lambdaUpdateWrapper.set(UserIntegral::getCbfunds, userIntegral.getCbfunds().add(cbfunds));
        } else {
            lambdaUpdateWrapper.set(UserIntegral::getCbfunds, userIntegral.getCbfunds().subtract(cbfunds));
        }
        lambdaUpdateWrapper.eq(UserIntegral::getUid, userIntegral.getUid());
        if (changeType.equals(IntegralDetailConstants.CHANGE_TYPE_DEC)) {
            lambdaUpdateWrapper.apply(StrUtil.format(" cbfunds - {} >= 0", cbfunds));
        }
        return update(lambdaUpdateWrapper);
    }


    @Override
    public Boolean operationIntegral(Integer uid, BigDecimal integral, BigDecimal nowIntegral, Integer changeType) {
        UpdateWrapper<UserIntegral> updateWrapper = new UpdateWrapper<>();
        if (changeType.equals(IntegralDetailConstants.CHANGE_TYPE_ADD)) {
            updateWrapper.setSql(StrUtil.format("integral = integral + {}", integral));
        } else {
            updateWrapper.setSql(StrUtil.format("integral = integral - {}", integral));
            updateWrapper.last(StrUtil.format(" and (integral - {} >= 0)", integral));
        }
        updateWrapper.eq("uid", uid);
        updateWrapper.eq("integral", nowIntegral);
        return update(updateWrapper);
    }

    /**
     * 操作增值积分
     * @param uid
     * @param integral
     * @param nowValueAddIntegral
     * @param changeType
     * @return
     */
    @Override
    public Boolean operationValueAddIntegral(Integer uid, BigDecimal integral, BigDecimal nowValueAddIntegral, Integer changeType) {
        UpdateWrapper<UserIntegral> updateWrapper = new UpdateWrapper<>();
        if (changeType.equals(IntegralDetailConstants.CHANGE_TYPE_ADD)) {
            updateWrapper.setSql(StrUtil.format("value_add_integral = value_add_integral + {}", integral));
        } else {
            updateWrapper.setSql(StrUtil.format("value_add_integral = value_add_integral - {}", integral));
            updateWrapper.last(StrUtil.format(" and (value_add_integral - {} >= 0)", integral));
        }
        updateWrapper.eq("uid", uid);
        updateWrapper.eq("value_add_integral", nowValueAddIntegral);
        return update(updateWrapper);
    }

    /**
     * 操作增值积分冻结部分
     * @param uid
     * @param integral
     * @param nowValueAddIntegral
     * @param changeType
     * @return
     */
    @Override
    public Boolean operationValueAddIntegralFreeze(Integer uid, BigDecimal integral, BigDecimal nowValueAddIntegral, Integer changeType) {
        UpdateWrapper<UserIntegral> updateWrapper = new UpdateWrapper<>();
        if (changeType.equals(IntegralDetailConstants.CHANGE_TYPE_ADD)) {
            updateWrapper.setSql(StrUtil.format("value_add_integral_freeze = value_add_integral_freeze + {}", integral));
        } else {
            updateWrapper.setSql(StrUtil.format("value_add_integral_freeze = value_add_integral_freeze - {}", integral));
        }
        updateWrapper.eq("uid", uid);
        updateWrapper.eq("value_add_integral_freeze", nowValueAddIntegral);
        return update(updateWrapper);
    }

    @Override
    public Boolean operationGreenIntegral(Integer uid, BigDecimal integral, BigDecimal nowGreenIntegral, Integer changeType) {
        UpdateWrapper<UserIntegral> updateWrapper = new UpdateWrapper<>();
        if (changeType.equals(IntegralDetailConstants.CHANGE_TYPE_ADD)) {
            updateWrapper.setSql(StrUtil.format("green_integral = green_integral + {}", integral));
        } else {
            updateWrapper.setSql(StrUtil.format("green_integral = green_integral - {}", integral));
            updateWrapper.last(StrUtil.format(" and (green_integral - {} >= 0)", integral));
        }
        updateWrapper.eq("uid", uid);
        updateWrapper.eq("green_integral", nowGreenIntegral);
        return update(updateWrapper);
    }

    @Override
    public Boolean operationGreenIntegralFreeze(Integer uid, BigDecimal integral, BigDecimal nowGreenIntegral, Integer changeType) {
        UpdateWrapper<UserIntegral> updateWrapper = new UpdateWrapper<>();
        if (changeType.equals(IntegralDetailConstants.CHANGE_TYPE_ADD)) {
            updateWrapper.setSql(StrUtil.format("green_integral_freeze = green_integral_freeze + {}", integral));
        } else {
            updateWrapper.setSql(StrUtil.format("green_integral_freeze = green_integral_freeze - {}", integral));
            updateWrapper.last(StrUtil.format(" and (green_integral - {} >= 0)", integral));
        }
        updateWrapper.eq("uid", uid);
        updateWrapper.eq("green_integral_freeze", nowGreenIntegral);
        return update(updateWrapper);
    }

    @Override
    public Boolean operationContributionIntegral(Integer uid, BigDecimal integral, BigDecimal nowContributionIntegral, Integer changeType) {
        UpdateWrapper<UserIntegral> updateWrapper = new UpdateWrapper<>();
        if (changeType.equals(IntegralDetailConstants.CHANGE_TYPE_ADD)) {
            updateWrapper.setSql(StrUtil.format("contribution_integral = contribution_integral + {}", integral));
        } else {
            updateWrapper.setSql(StrUtil.format("contribution_integral = contribution_integral - {}", integral));
            updateWrapper.last(StrUtil.format(" and (contribution_integral - {} >= 0)", integral));
        }
        updateWrapper.eq("uid", uid);
        updateWrapper.eq("contribution_integral", nowContributionIntegral);
        return update(updateWrapper);
    }

    @Override
    public Boolean operationBalance(Integer uid, BigDecimal integral, BigDecimal nowBalance, Integer changeType) {
        UpdateWrapper<UserIntegral> updateWrapper = new UpdateWrapper<>();
        if (changeType.equals(IntegralDetailConstants.CHANGE_TYPE_ADD)) {
            updateWrapper.setSql(StrUtil.format("balance = balance + {}", integral));
        } else {
            updateWrapper.setSql(StrUtil.format("balance = balance - {}", integral));
            updateWrapper.last(StrUtil.format(" and (balance - {} >= 0)", integral));
        }
        updateWrapper.eq("uid", uid);
        updateWrapper.eq("balance", nowBalance);
        return update(updateWrapper);
    }

    @Override
    public Boolean operationCbfunds(Integer uid, BigDecimal integral, BigDecimal nowCbfunds, Integer changeType) {
        UpdateWrapper<UserIntegral> updateWrapper = new UpdateWrapper<>();
        if (changeType.equals(IntegralDetailConstants.CHANGE_TYPE_ADD)) {
            updateWrapper.setSql(StrUtil.format("cbfunds = cbfunds + {}", integral));
        } else {
            updateWrapper.setSql(StrUtil.format("cbfunds = cbfunds - {}", integral));
            updateWrapper.last(StrUtil.format(" and (cbfunds - {} >= 0)", integral));
        }
        updateWrapper.eq("uid", uid);
        updateWrapper.eq("cbfunds", nowCbfunds);
        return update(updateWrapper);
    }


    @Override
    public List<UserIntegralDetail> findListByOrderIdAndUid(String orderNo, Integer uid) {
        return null;
    }

//    @Override
//    public PageInfo<UserIntegralResponse> findAdminValueAddList(AdminIntegralSearchRequest request, PageParamRequest pageParamRequest) {
//        Page<UserIntegralResponse> page = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
//        LambdaQueryWrapper<UserIntegral> lqw = Wrappers.lambdaQuery();
//        lqw.select(UserIntegral::getId,UserIntegral::getValueAddIntegral,
//                UserIntegralRecord::getMark, UserIntegralRecord::getUid, UserIntegralRecord::getUpdateTime);
//        lqw.eq(UserIntegralRecord::getStatus, IntegralRecordConstants.INTEGRAL_RECORD_STATUS_COMPLETE);
//        if (ObjectUtil.isNotNull(request.getUid())) {
//            lqw.eq(UserIntegralRecord::getUid, request.getUid());
//        }
//        if (StrUtil.isNotBlank(request.getKeywords())) {
//            List<Integer> idList = userService.findIdListLikeName(request.getKeywords());
//            if (CollUtil.isNotEmpty(idList)) {
//                lqw.in(UserIntegralRecord::getUid, idList);
//            } else {
//                return CommonPage.copyPageInfo(page, CollUtil.newArrayList());
//            }
//        }
//        //时间范围
//        if (StrUtil.isNotBlank(request.getDateLimit())) {
//            dateLimitUtilVo dateLimit = DateUtil.getDateLimit(request.getDateLimit());
//            //判断时间
//            int compareDateResult = DateUtil.compareDate(dateLimit.getEndTime(), dateLimit.getStartTime(), Constants.DATE_FORMAT);
//            if (compareDateResult == -1) {
//                throw new CrmebException("开始时间不能大于结束时间！");
//            }
//
//            lqw.between(UserIntegralRecord::getUpdateTime, dateLimit.getStartTime(), dateLimit.getEndTime());
//        }
//        lqw.orderByDesc(UserIntegralRecord::getUpdateTime);
//        List<UserIntegralRecord> list = dao.selectList(lqw);
//        if (CollUtil.isEmpty(list)) {
//            return CommonPage.copyPageInfo(page, CollUtil.newArrayList());
//        }
//        List<UserIntegralRecordResponse> responseList = list.stream().map(i -> {
//            UserIntegralRecordResponse response = new UserIntegralRecordResponse();
//            BeanUtils.copyProperties(i, response);
//            // 获取用户昵称
//            User user = userService.getById(i.getUid());
//            if (ObjectUtil.isNotNull(user)) {
//                response.setNickName(user.getNickname());
//            } else {
//                response.setNickName("");
//            }
//            return response;
//        }).collect(Collectors.toList());
//        return CommonPage.copyPageInfo(page, responseList);
//    }
//
//    @Override
//    public PageInfo<UserIntegralResponse> findAdminGreenList(AdminIntegralSearchRequest request, PageParamRequest pageParamRequest) {
//        return null;
//    }
//
//    @Override
//    public PageInfo<UserIntegralResponse> findAdminContributionList(AdminIntegralSearchRequest request, PageParamRequest pageParamRequest) {
//        return null;
//    }
//
//    @Override
//    public PageInfo<UserIntegralResponse> findAdminBalanceList(AdminIntegralSearchRequest request, PageParamRequest pageParamRequest) {
//        return null;
//    }
//
//    @Override
//    public PageInfo<UserIntegralResponse> findAdminCbfundsList(AdminIntegralSearchRequest request, PageParamRequest pageParamRequest) {
//        return null;
//    }




    /**
     * 根据类型条件计算积分总数
     * @param uid 用户uid
     * @return 积分总数
     */


    @Override
    public UserIntegral getSumValueAddIntegral(Integer uid) { // 获取增值积分
        QueryWrapper<UserIntegral> queryWrapper = new QueryWrapper<>();
        //queryWrapper.select("sum(value_add_integral) as value_add_integral");
        queryWrapper.eq("uid", uid);
        //if (ObjectUtil.isNull(integralRecord) || ObjectUtil.isNull(integralRecord.getValueAddIntegral())) {
        //    System.out.println("valueAdd 为0........");
        //    return new BigDecimal(0);
        //}
        return dao.selectOne(queryWrapper);
    }

    public UserIntegral getSumGreenIntegral(Integer uid) { // 获取绿色积分
        QueryWrapper<UserIntegral> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("uid", uid);
        return dao.selectOne(queryWrapper);
    }

    @Override
    public BigDecimal getSumContributionIntegral(Integer uid) { // 获取贡献值
        QueryWrapper<UserIntegral> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("sum(contribution_integral) as contribution_integral");
        queryWrapper.eq("uid", uid);
        UserIntegral integralRecord = dao.selectOne(queryWrapper);
        if (ObjectUtil.isNull(integralRecord) || ObjectUtil.isNull(integralRecord.getContributionIntegral())) {
            System.out.println("contribution 为0........");
            return new BigDecimal(0);
        }
        return integralRecord.getContributionIntegral();
    }

    @Override
    public BigDecimal getSumBalance(Integer uid) { // 获取余额
        QueryWrapper<UserIntegral> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("sum(balance) as balance");
        queryWrapper.eq("uid", uid);
        UserIntegral integralRecord = dao.selectOne(queryWrapper);
        if (ObjectUtil.isNull(integralRecord) || ObjectUtil.isNull(integralRecord.getBalance())) {
            System.out.println("balance 为0........");
            return new BigDecimal(0);
        }
        return integralRecord.getBalance();
    }

    @Override
    public BigDecimal getSumCbfunds(Integer uid) { // 获取cb基金
        QueryWrapper<UserIntegral> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("sum(cbfunds) as cbfunds");
        queryWrapper.eq("uid", uid);
        UserIntegral integralRecord = dao.selectOne(queryWrapper);
        if (ObjectUtil.isNull(integralRecord) || ObjectUtil.isNull(integralRecord.getCbfunds())) {
            System.out.println("cbfunds 为0........");

            return new BigDecimal(0);
        }
        return integralRecord.getCbfunds();
    }

//    /**
//     * H5用户积分列表
//     * @param uid 用户uid
//     * @param pageParamRequest 分页参数
//     * @return 记录列表
//     */
//
//    @Override
//    public List<UserIntegral> findUserValueAddIntegralList(Integer uid, PageParamRequest pageParamRequest) {
//        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
//        LambdaQueryWrapper<UserIntegral> lqw = Wrappers.lambdaQuery();
//        lqw.select(UserIntegral::getId, UserIntegral::getValueAddIntegral);
//        lqw.eq(UserIntegral::getUid, uid);
//        return dao.selectList(lqw);
//    }
//
//    @Override
//    public List<UserIntegral> findUserGreenIntegralList(Integer uid, PageParamRequest pageParamRequest) {
//        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
//        LambdaQueryWrapper<UserIntegral> lqw = Wrappers.lambdaQuery();
//        lqw.select(UserIntegral::getId, UserIntegral::getGreenIntegral);
//        lqw.eq(UserIntegral::getUid, uid);
//        return dao.selectList(lqw);
//    }
//    @Override
//    public List<UserIntegral> findUserContributionIntegralList(Integer uid, PageParamRequest pageParamRequest) {
//        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
//        LambdaQueryWrapper<UserIntegral> lqw = Wrappers.lambdaQuery();
//        lqw.select(UserIntegral::getId, UserIntegral::getContributionIntegral);
//        lqw.eq(UserIntegral::getUid, uid);
//        return dao.selectList(lqw);
//    }
//
//    @Override
//    public List<UserIntegral> findUserBalanceList(Integer uid, PageParamRequest pageParamRequest) {
//        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
//        LambdaQueryWrapper<UserIntegral> lqw = Wrappers.lambdaQuery();
//        lqw.select(UserIntegral::getId, UserIntegral::getBalance);
//        lqw.eq(UserIntegral::getUid, uid);
//        return dao.selectList(lqw);
//    }
//
//    @Override
//    public List<UserIntegral> findUserCbfundsList(Integer uid, PageParamRequest pageParamRequest) {
//        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
//        LambdaQueryWrapper<UserIntegral> lqw = Wrappers.lambdaQuery();
//        lqw.select(UserIntegral::getId, UserIntegral::getCbfunds);
//        lqw.eq(UserIntegral::getUid, uid);
//        return dao.selectList(lqw);
//    }

}

